/**
 * Created with JetBrains WebStorm.
 * User: kjhbond
 * Date: 13. 5. 22
 * Time: 오전 11:07
 * To change this template use File | Settings | File Templates.
 */
var Progress = {

    status : 0,
    bar : null,

    ON : function(){
        if( this.status == 1 ) return;
        this.status = 1;

        this.bar.style.height = document.body.scrollHeight + "px";

        bm.addChild( this.bar, window.document.body );
    },

    OFF : function(){
        if( this.status == 0 ) return;
        this.status = 0;
        window.document.body.removeChild( this.bar );
    }
}

Progress.bar = bm.html('<div style="width:100%; height:100%; text-align: center; position: absolute; top: 0; left: 0; z-index: 99999; background: #000; opacity: 0.5; filter:alpha(opacity=50);"></div>');
var progressImgUrl = window.progressImgUrl || '../js/progress.gif';
bm.imageLoader( function( list ){
    var img = list[0];
    bm.setStyles( img, { position:'absolute', top:'50%', marginTop:'-20px', left:'50%', marginLeft:'-20px' } )
    Progress.bar.appendChild( img );
}, progressImgUrl);


var util = {
    getIndex : function( list, cts ){
        for( var i = 0; i<list.length; i++ ) {
            if( cts !=null &&  list[ i ] != null && list[ i ] == cts	) return i;
        }
    },

    //     팝업
    onPopup : function(url, title, width, height){

        var x = document.body.clientWidth-width>>1;
        var y = document.body.clientHeight-height>>1;

        y = y/2;

        window.open(url, title, 'left='+x+', top='+y+'resizable=no, scrollbars=no, width='+width+', height='+height );
    }


    ,formCheck : function( formName, chkList /* check 해야할 input 의 name 배열.*/ , compareValue/* 비교할 기본값. */,  msgList /* check 에서 false 가 나오면 나오는 메시지. ( 없어도 무방 ) */, defaultMsg /* 기본 메시지. ( 없어도 무방 ) */ ){
        var f = document[formName];
        var len = chkList.length;
        var input, msg;
        var cv, result;
        msgList = msgList || [];
        compareValue = compareValue || [];
        defaultMsg = defaultMsg || "필수항목을 모두 채워주세요.";

        for( var i = 0; i<len; i++ ){
            input = f[chkList[i]];

            if( !input ){
                alert( "ERROR ==> form 에 없는 값을 체크하려 하였습니다. [ " + chkList[i] + " ]" );
                return false;
            }

            cv = compareValue[i];

            if( !input.type ){

                var type = input[0].type;
                var subLen = input.length;
                var k;

                // radio, checkbox
                if( type == "radio" || type == "checkbox" ){

                    var subValue = null;
                    for( k=0; k<subLen; k++ ){
                        if(input[k].checked && input[k].value ) {
                            subValue = input[k].value;
                            break;
                        }
                    }
                    if( !subValue ) return false;

                // array input list
                }else{
                    for( k=0; k<subLen; k++ ){
                        result = check( input[k], cv );
                        if( result == false ) return false;
                    }
                }

            }else{
                result = check( input, cv );
                if( result == false ) return false;
            }
        }

        function check( field, checkValue ){
            if( !field.value || field.value == checkValue ){
                msg = msgList[i] || defaultMsg;
                field.focus();
                alert( msg );
                return false;
            }else{
                return true;
            }
        }

        return true;
    }

    ,textInputDefaultList : {}
    ,__registTextInput : function( input ){
        var _this = this;
        input.onfocus = function(){
            _this.textInputDefaultList[ this ] = this.value;
            this.value = "";
        }

        input.onblur = function(){
            if (this.value == "" ) this.value = _this.textInputDefaultList[ this ];
        }
    }
    ,registTextInput : function( input ){
        if( input.length ){
            var len = input.length;
            for( var i=0; i<len; i++ ){
                this.__registTextInput( input[i] );
            }
        }else this.__registTextInput( input );
    }



}


var form = function( formName, chkList /* check 해야할 input 의 name 배열.*/, compareValue, extraData ){

    this.onSubmit = null; // submit 시에 콜백 핸들러. ( true / false 반환 )
    this.onSubmitComplete = null; // submit 시에 콜백 핸들러. ( true / false 반환 )
    this.async = true; // 비동기 방식으로 처리할 것인지.
    this.confirmReturnValue = 'true'; // 성공시 리턴받아 비교할 값.
    this.confirmUrl = '';
    this.confirmMsg = '';
    this.failMsg = ''; // 통신 fail 메시지
    this.invalidMsgList = [];
    this.defaultInvalidMsg = "";
    this.onSubmitMsg = "";
    this.status = true; // 전송여부.

    var _this = this;
    var f = document[formName];
    this.form = f;

    this.cancelSubmit = function(){
        _this.status = false;
    }

    $(f).find( 'input[type="submit"], input[type="image"]').on( 'click', function(){
        if(_this.onSubmitMsg){
            if(confirm(_this.onSubmitMsg)) return _this.start();
            else return false;
        }else return _this.start();
    });

    this.start = function(){
        _this.status = true;
        if( _this.onSubmit ) _this.onSubmit();
        if( _this.status == false ) return false;

        Progress.ON();

        var result = util.formCheck( formName, chkList, compareValue, _this.invalidMsgList, _this.defaultInvalidMsg );

        if( result && _this.async ) {

            var o = {};

            var inputList = $(f).find('input, textarea, select').not('input[type="radio"], input[type="checkbox"]');
            var len = inputList.length;
            var input;
            for( var i = 0; i<len; i++ ){
                input = inputList[ i ];
                if( /submit|image/i.test( input.type ) ) continue;
                o[input.name] = input.value;
            }

            inputList = $(f).find('input[type="radio"], input[type="checkbox"]');
            len = inputList.length;
            for( i = 0; i<len; i++ ){
                input = inputList[ i ];
                if( input.checked ) o[input.name] = input.value;
            }

            o.async = 'true';

            if( extraData ){
                for( var key in extraData ) o[key] = extraData[key];
            }

            $.ajax({
                url : f.action,
                type: "POST",
                data : o,
                success:function(msg){
                    if( _this.onSubmitComplete ) _this.onSubmitComplete( msg );
                    if( msg.indexOf( _this.confirmReturnValue ) > -1 ){
                        _this.confirmMsg && alert( _this.confirmMsg );
                        if( _this.confirmUrl ) window.location.href = _this.confirmUrl;
                    }else{
                        _this.failMsg && alert( _this.failMsg );
                    }

                    Progress.OFF();
                }
            });
            return false;
        }
        else {
            Progress.OFF();
            return result;
        }
    }
}


var formMultipart = function( formName, chkList /* check 해야할 input 의 name 배열.*/, compareValue, extraData ){
    this.onSubmit = null; // submit 시에 콜백 핸들러. ( true / false 반환 )
    this.onSubmitComplete = null; // submit 시에 콜백 핸들러. ( true / false 반환 )
    this.async = true; // 비동기 방식으로 처리할 것인지.
    this.confirmReturnValue = 'true'; // 성공시 리턴받아 비교할 값.
    this.confirmUrl = '';
    this.confirmMsg = '';
    this.failMsg = ''; // 통신 fail 메시지
    this.invalidMsgList = [];
    this.defaultInvalidMsg = "";
    this.onSubmitMsg = "";
    this.status = true; // 전송여부.

    var _this = this;
    var f = document[formName];
    this.form = f;

    this.cancelSubmit = function(){
        _this.status = false;
    }

    $(f).find( 'input[type="submit"], input[type="image"]').on( 'click', function(){
        if(_this.onSubmitMsg){
            if(confirm(_this.onSubmitMsg)) return _this.start();
            else return false;
        }else return _this.start();
    });

    this.start = function(){
        _this.status = true;
        if( _this.onSubmit ) _this.onSubmit();

        if( _this.status == false ) return false;

        Progress.ON();
        var result = util.formCheck( formName, chkList, compareValue, _this.invalidMsgList, _this.defaultInvalidMsg );
        if( result && _this.async ) {

            if( f.async && f.async.value == 'false' ) f.async.value = 'true';


            var o = {};
            if( extraData ){
                for( var key in extraData ) o[key] = extraData[key];
            }

            $(f).ajaxForm( {
                data : o,
                uploadProgress: function(event, position, total, percentComplete) {
                },
                complete : function(msg){
                    msg = msg.responseText; // ajaxForm 에서는 이곳에 return value 를 넣어준다.
                    if( _this.onSubmitComplete ) _this.onSubmitComplete( msg );
                    if( msg.indexOf( _this.confirmReturnValue ) > -1 ){
                        _this.confirmMsg && alert( _this.confirmMsg );
                        if( _this.confirmUrl ) window.location.href = _this.confirmUrl;
                    }else{
                        _this.failMsg && alert( _this.failMsg );
                    }

                    Progress.OFF();
                }
            } );

            $(f).submit();

            return false;
        }
        else{
            Progress.OFF();
            return result;
        }
    }
}

/**
 * GlobalNavigationBar
 */
function GlobalNavigationBar( container ){

    var gnb = this;

    var activeIndex = [];
    var conList = [];
    var conOnList = [];
    var btnList = [];
    var btnActiveList = [];
    var conOnStyleList = [];
    var conOffStyleList = [];
    var tweenDuration = 0.3;
    var tweenEasing = Cubic.easeOut;

    this.container = container;
    this.selectedIndex = [];
    this.mouseOutActive = false; // 마우스 아웃 활성화 여부.
    this.mouseOutActiveContainer = true; // 컨테이너 마우스 아웃 활성화 여부.

    $(this.container).hover(function(){

    },function(){
        if( gnb.mouseOutActiveContainer == false ) return;
        gnb.reset();
        activeIndex = gnb.selectedIndex.concat();
        gnb.indexControl();
    })


    this.setSub = function( thisSelector, btnSelector, thisOnClass, btnActiveClass, conOnStyle, conOffStyle ){

        var depth = conList.length;
        if( thisOnClass ) conOnList[ depth ] = thisOnClass;
        if( btnActiveClass ) btnActiveList[ depth ] = btnActiveClass;
        if( btnSelector ) btnList[ depth ] = btnSelector;
        if( conOnStyle ) conOnStyleList[ depth ] = conOnStyle;
        if( conOffStyle ) conOffStyleList[ depth ] = conOffStyle;


        var parentSelector = '';
        var len = depth;
        var i;
        var parent = $(this.container);
        if( len > 0 ){

            var addStr = "";
            for( i=0; i<len; i++ ){
                parentSelector += addStr + conList[i];
                addStr = " ";
            }

            if( btnList[conList.length-1] ) parentSelector += btnList[conList.length-1];
            parent = $(this.container).find(parentSelector);
        }


        var selector = thisSelector;
        if( btnSelector ) selector += btnSelector;
        conList.push( thisSelector );

        for( i=0; i<parent.length; i++ ){
            var currParent = parent[i];
            setMouseEvent( currParent, selector, depth );
        }

        return gnb;
    }

    this.setDuration = function( duration ){
        tweenDuration = duration;
    }

    this.setEasing = function( easing ){
        tweenEasing = easing;
    }

    this.addMotion = function( overSelector, outSelector, element, overStyle, outStyle, duration, ease ){

        element = $(element);

        $(overSelector).hover(function(){

            var o = {};
            for( var key in overStyle ){
                var value = overStyle[key];
                o[key] = value instanceof Array ? value[ activeIndex[ 0 ] ] : value;
            }

            o.ease = ease ? ease : tweenEasing;
            duration = duration ? duration : tweenDuration;

            TweenMax.killTweensOf( element );
            TweenMax.to( element, duration, o );
        })

        $(outSelector).hover(function(){
        },function(){

            var o = {};
            for( var key in outStyle ){
                var value = outStyle[key];
                o[key] = value instanceof Array ? value[ activeIndex[ 0 ] ] : value;
            }

            o.ease = ease ? ease : tweenEasing;
            duration = duration ? duration : tweenDuration;

            TweenMax.killTweensOf( element );
            TweenMax.to( element, duration, o );
        })

    }




    function setMouseEvent( parent, selector, depth ){
        $(parent).find(selector).hover( function(e){
            e.stopPropagation();

            gnb.reset();
            activeIndex[ depth ] = util.getIndex( $(parent).find(selector), this );
            activeIndex.length = depth+1;
            gnb.indexControl();

        },function(){
            if( gnb.mouseOutActive ){
                gnb.reset();

                if( depth == 0 ) activeIndex = gnb.selectedIndex.concat();
                else activeIndex.length = depth;

                gnb.indexControl();
            }
        });
    }

    this.setIndex = function(){
        var len = arguments.length;
        for( var i=0; i<len; i++ ){
            this.selectedIndex[i] = arguments[i];
        }

        this.reset();

        activeIndex = this.selectedIndex.concat();

        this.indexControl();
    }

    this.indexControl = function(){

        var depth;
        var len = activeIndex.length;
        var selector, currSub;
        currSub = $(this.container);

        for( var i=0; i<len; i++ ){
            depth = i;
            if( activeIndex[depth] == -1 || activeIndex[depth] == undefined || activeIndex[depth] == null ) break;

            selector = conList[ depth ]+( btnList[depth] ? btnList[depth] : '' );
            currSub = $(currSub).find(selector)[ activeIndex[depth] ];
            ON( depth, currSub );
        }
    }


    this.reset = function(){
        var depth;
        var len = activeIndex.length;
        var selector, currSub;
        currSub = $(this.container);
        for( var i=0; i<len; i++ ){
            depth = i;
            if( activeIndex[depth] == -1 || activeIndex[depth] == undefined || activeIndex[depth] == null ) break;
            selector = conList[depth]+( btnList[depth] ? btnList[depth] : '' );
            currSub = $(currSub).find(selector)[activeIndex[depth]];
            OFF( depth, currSub );
        }
    }


    this.init = function(){
        var depth;
        var len = conList.length;
        var selector, currSub;
        currSub = $(this.container);
        for( var i=0; i<len; i++ ){
            depth = i;
            selector = conList[depth]+( btnList[depth] ? btnList[depth] : '' );

            var subList = $(currSub).find(selector);
            var subLen = subList.length;
            while( subLen-- ){
                OFF( depth, subList[ subLen ], true );
            }

        }
    }


    function ON( depth, element ){

        if( btnActiveList[depth] ) {
            $(element).addClass( btnActiveList[depth] );
        } // 현재버튼 활성화
        if( conList.length-1 > depth ) {

            // 현재버튼의 서브 보임
            var subCon = $(element).find( conList[depth+1] )[0];
            if( conOnList[depth+1] ) {
                $(subCon).addClass( conOnList[depth+1] );
            }

            // 현재버튼 아래 자식의 등장시 적용 스타일이 존재하면.... ( 적용 스타일이 배열에 추가되었다면, 자식 자체가 셋팅되었다는 말이므로.. )
            if( conOnStyleList[depth+1] && subCon ){

                var o = {};
                o.ease = o.ease || tweenEasing;

                TweenMax.killTweensOf( subCon );

                var d = conOnStyleList[depth+1];
                for( var key in d ){
                    var value = d[key];
                    o[key] = value instanceof Array ? value[ activeIndex[ depth ] ] : value;
                }

                TweenMax.to( subCon, tweenDuration, o );
            }
        }
    }

    function OFF( depth, element, isInit ){

        if( btnActiveList[depth] ) {
            $(element).removeClass( btnActiveList[depth] );
        }
        if( conList.length-1 > depth ) {
            var subCon = $(element).find( conList[depth+1] )[0];

            if( conOffStyleList[depth+1] && subCon ){

                var o = {};
                o.ease = o.ease || tweenEasing;

                TweenMax.killTweensOf( subCon );

                var d = conOffStyleList[depth+1];

                for( var key in d ){
                    var value = d[key];
                    o[key] = value instanceof Array ? value[ activeIndex[ depth ] ] : value;
                }

                o.onComplete = removeClass;
                o.onCompleteParams = [subCon, conOnList[depth+1]];

                var dur = isInit ? 0 : tweenDuration;
                TweenMax.to( subCon, dur, o );
            }else{
                removeClass( subCon, conOnList[depth+1] );
            }
        }

        function removeClass( con, css ){
            if( css ) $( con ).removeClass( css );
        }
    }

}





function cutStr( str, startIndex, endIndex ){
    endIndex = ( str.length > endIndex ) ? endIndex : str.length;
    return str.substring( 0, startIndex ) + str.substring( endIndex, str.length);
}

function parseStrToObj( str, obj ){

    if( !obj ) {
        obj = {};
        str = str.replace( /\s/g , "" ); // 공백제거.
        str = str.substr( 1, str.length-2 ); // 맨앞, 맨뒤 {} 제거.
    }

    while( str.indexOf( "{" ) > -1 ){

        // value 추출.
        var stIdx = str.indexOf( "{" );
        var edIdx = str.indexOf( "}" )+1;
        var sub = str.slice( str.indexOf( "{" )+1, str.indexOf( "}" ) ); // "{" 다음부터 "}" 이전까지 잘라서 다시 파싱한다.
        var value = {};
        parseStrToObj( sub, value );

        // 원본 수정.
        str = cutStr( str, stIdx, edIdx );

        // key 추출
        edIdx = ( str.charAt( str.length-1 ) == ":" ) ? str.length-1 : str.indexOf( ":," );
        stIdx = str.lastIndexOf( ",", edIdx ) == -1 ? 0 : str.lastIndexOf( ",", edIdx );
        var key = str.slice( stIdx, edIdx );

        // 원본 수정
        str = cutStr( str, stIdx, edIdx+2 );

        // key : value 대입.
        obj[ key ] = value;
    }

    // 단일뎁스 String 을 obj 로 변환.
    var list = str.split( "," );
    var len = list.length;
    var o;
    while( len-- ){
        o = list[len].split( ":" );
        obj[ o[0] ] = o[1];
    }

    return obj;
}

var effectList = [];
var rollList = [];
var sfList = [];

function preloadImages(selector) {
    $(selector).find('img').each(function() {
        var img = $(this),
            src = img.attr('src');

        img.css('filter', "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled='true',sizingMethod='scale',src='" + src + "')");
    });
}

$( function(){

    var fps = bm.enterFPS;
    var item = $( document.body ).find( "[effect]" );
    var len, i, o;
    if( item && item.length > 0 ){
        len = item.length;
        for( i = 0; i<len; i++ ){

            o = parseStrToObj( $(item[i]).attr("effect") );
            if( !o["mode"] ) o.mode = "fadeOut";

            o.intervalCnt = o.intervalCnt == undefined ? 0 : Math.floor( parseFloat( o.intervalCnt ) * fps );
            o.target = o.selector ? $(item[i]).find(o.selector)[0] : item[i];
            o.intervalIn = Math.floor( parseFloat( o.intervalIn ? o.intervalIn : 0 ) * fps );
            o.intervalOut = Math.floor( parseFloat( o.intervalOut ? o.intervalOut : 0 ) * fps );

            effectList.push( o );

            preloadImages(item[i]);
        }
    }


    var scrollFollow = $( document.body ).find( "[scrollFollow]" );
    if( scrollFollow && scrollFollow.length > 0 ){
        len = scrollFollow.length;
        for( i = 0; i<len; i++ ){
            o = parseStrToObj( $(scrollFollow[i]).attr("scrollFollow") );
            o.target = scrollFollow[i];
            o.duration = o.duration ? parseFloat( o.duration ) : 1;
            o.top = scrollFollow[i].offsetTop;
            sfList.push( o );
        }
    }


    var rolling = $( document.body ).find( "[rolling]" );
    rolling.css( 'position', 'absolute' );
    var conWid, conHei;
    if( rolling && rolling.length > 0 ){
        len = rolling.length;
        for( i = 0; i<len; i++ ){

            o = parseStrToObj( $(rolling[i]).attr("rolling") );
            o.con = rolling[i];
            o.childSelector = o.childSelector ? o.childSelector : "li";

            // 자식 셋팅
            o.list = $(rolling[i]).find( o.childSelector );
            o.pos = [];
            o.targetPos = [];


            ( function(o){
                o.direction = o.direction ? o.direction : "left";
                o.interval = Math.floor( parseFloat( o.interval ? o.interval : 0 ) * fps );
                o.duration = parseFloat( o.duration ? o.duration : 0 );
                o.ease = o.ease ? o.ease : Cubic.easeInOut;
                o.unlimit = o.unlimit == "true" ? true : false;
                o.auto = o.auto == "true" ? true : false;
                o.mouseResponceOff = o.mouseResponceOff == "false" ? false : true;
                o.mouseResponceOffTarget = o.mouseResponceOffTarget == undefined ? $( o.con ) : ( o.mouseResponceOffTarget == "this" ? $( o.con ) : $(o.mouseResponceOffTarget) );
                o.mouseHover = false;
                o.viewNum = o.viewNum == undefined ? 1 : parseInt( o.viewNum );
                o.index = o.preIndex = 0;
                o.loadLen = o.list.find( 'img' ).length;
                o.loaded = 0;
                o.intervalCnt = 0;

                function loaded(){
                    var idx = o.list.find( 'img' ).index(this);
                    var li = o.list[idx];
                    var l = o.con.offsetWidth / ( ( o.direction == "left" || o.direction == "right" ) ? o.viewNum : 1 ) - li.offsetWidth >> 1;
                    var t = o.con.offsetHeight / ( ( o.direction == "top" || o.direction == "bottom" ) ? o.viewNum : 1 ) - li.offsetHeight >> 1;
                    o.pos[idx] = {left:l,top:t};

                    if(o.targetPos[idx]){
                        l += o.targetPos[idx].left;
                        t += o.targetPos[idx].top;
                    }
                    $(li).css('left', l).css('top', t);

                    o.loaded++;
                    if(o.loaded == o.loadLen){
                        defaultSetting( o );
                    }
                }

                o.list.css( 'position', 'absolute' );
                if( o.loadLen == o.list.length ){

                    o.list.find( 'img' ).each( function(){

                        if( this.offsetWidth && this.offsetHeight ){
                            loaded.apply( this );
                        }else{
                            this.onload = function(){
                                loaded.apply( this );
                            }
                        }
                    });
                }

                if( o.mouseResponceOff ){
                    o.mouseResponceOffTarget.hover( function(){
                        o.mouseHover = true;
                    }, function(){
                        o.mouseHover = false;
                    });
                }

                if(o.keyNext){
                    $(o.keyNext).css('cursor','pointer').on( "click" , function( e ){
                        next( o );
                    });
                }

                if(o.keyPrev){
                    $(o.keyPrev).css('cursor','pointer').on( "click" , function( e ){
                        prev( o );
                    });
                }

                if(o.keyPause){
                    $(o.keyPause).css('cursor','pointer').on( "click" , function( e ){
                        o.auto = false;
                        $(o.keyPause).hide();
                        $(o.keyPlay).show();
                    });
                }

                if(o.keyPlay){
                    $(o.keyPlay).css('cursor','pointer').on( "click" , function( e ){
                        o.auto = true;
                        $(o.keyPause).show();
                        $(o.keyPlay).hide();
                    });
                }

                defaultSetting( o );

                function defaultSetting( o ){
                    var len = o.list.length;
                    var targetLeft, targetTop;
                    for( var i = 0; i<len; i++ ){

                        if( o.direction == "left" || o.direction == "right" ){
                            targetLeft = o.con.offsetWidth / o.viewNum * (i-o.index) + ( o.pos[i] ? o.pos[i].left : 0 );
                            targetTop = ( o.pos[i] ? o.pos[i].top : 0 );
                        }else if( o.direction == "top" || o.direction == "bottom" ){
                            targetLeft = ( o.pos[i] ? o.pos[i].left : 0 );
                            targetTop = o.con.offsetHeight / o.viewNum * (i-o.index) + ( o.pos[i] ? o.pos[i].top : 0 );
                        }

                        o.targetPos[i] = {left:targetLeft, top:targetTop };
                        o.list[i].style.left = o.targetPos[i].left + "px";
                        o.list[i].style.top = o.targetPos[i].top + "px";
                    }
                }
            })( o );
            rollList.push( o );
        }
    }

    if( ( item && item.length > 0 ) ||
        ( rolling && rolling.length > 0 ) )
    {
        bm.onEnterRegist( onEnter );
    }


    $(window).scroll( function(){
        var scrollTop = $(window).scrollTop();
        var len = sfList.length;
        var o;
        for( var i = 0; i<len; i++ ){

            o = sfList[i];
            TweenMax.killTweensOf(o.target);
            TweenMax.to(o.target, o.duration, {top: o.top + scrollTop , ease:Cubic.easeOut} );

        }
    })
});



function onEnter(){

    var len = effectList.length;
    var o;
    while( len-- ){
        o = effectList[ len ];
        o.intervalCnt++;
        if(o.mode == "fadeIn" && o.intervalOut < o.intervalCnt ) play( o );
        else if( o.mode == "fadeOut" && o.intervalIn < o.intervalCnt ) play( o );
    }

    len = rollList.length;
    while( len-- ){
        o = rollList[ len ];
        if( o.mouseResponceOff && o.mouseHover ) continue;
        if( o.auto ){
            o.intervalCnt++;
            if( o.interval < o.intervalCnt ){
                if( o.direction == "left" ) next(o);
                else if( o.direction == "right" ) prev(o);
            }
        }
    }
}

function play( o ){
    if(o.mode == "fadeIn" && !o.fadeIn ) return;
    if(o.mode == "fadeOut" && !o.fadeOut ) return;

    TweenMax.to(o.target, o.duration, o.mode == "fadeIn" ? o.fadeIn : o.fadeOut );
    o.mode = o.mode == "fadeIn" ? "fadeOut" : "fadeIn";
    o.intervalCnt = 0;
}

function prev( o ){
    if( o.intervalCnt < bm.enterFPS/2 ) return; // 무한클릭 방지 0.5초.
    o.direction = "right";
    o.preIndex = o.index;
    o.intervalCnt = 0;
    o.index--;
    if(o.index == -1 ){
        if( o.unlimit ){
            o.index = o.list.length-1;
            rollIndexControl( o );
        }else{
            o.index = 0;
        }
    }else{
        rollIndexControl( o );
    }
}

function next( o ){
    if( o.intervalCnt < bm.enterFPS/2 ) return; // 무한클릭 방지 0.5초.
    o.direction = "left";
    o.preIndex = o.index;
    o.intervalCnt = 0;
    o.index++;
    if(o.index == o.list.length){
        if( o.unlimit ){
            o.index = 0;
            rollIndexControl( o );
        }else{
            o.index = o.list.length-1;
        }
    }else{
        rollIndexControl( o );
    }
}

function rollIndexControl( o ){

    function getRealIdx( idx ){
        if( idx > o.list.length-1 ) idx = idx - o.list.length;
        else if( idx < 0 ) idx = o.list.length + idx;
        return idx;
    }


    if( o.direction == "left" || o.direction == "top" ){
        len = o.viewNum+1;
        idx = o.index-1;
        while( len-- ) moveItem( o, getRealIdx(idx++) );
    }else if( o.direction == "right" || o.direction == "bottom" ){
        len = o.viewNum+1;
        idx = o.index;
        while( len-- ) moveItem( o, getRealIdx(idx++) );
    }
}

function moveItem( o, i ){
    var targetLeft, targetTop;
    var diffNum = i - o.index;
    if( i - o.index < 0 ){
        diffNum += o.list.length;
    }

    if( diffNum - o.viewNum > 0 ){
        switch(o.direction){
            case "left" :
                targetLeft = -o.con.offsetWidth / o.viewNum + ( o.pos[i] ? o.pos[i].left : 0 );
                targetTop = ( o.pos[i] ? o.pos[i].top : 0 );
                break;
            case "right" :
                targetLeft = o.con.offsetWidth / o.viewNum + ( o.pos[i] ? o.pos[i].left : 0 );
                targetTop = ( o.pos[i] ? o.pos[i].top : 0 );
                break;
            case "top" :
                targetLeft = ( o.pos[i] ? o.pos[i].left : 0 );
                targetTop = -o.con.offsetHeight / o.viewNum + ( o.pos[i] ? o.pos[i].top : 0 );
                break;
            case "bottom" :
                targetLeft = ( o.pos[i] ? o.pos[i].left : 0 );
                targetTop = o.con.offsetHeight / o.viewNum + ( o.pos[i] ? o.pos[i].top : 0 );
                break;
        }
    }else{
        switch(o.direction){
            case "left" :
                o.list[i].style.left = o.con.offsetWidth / o.viewNum * (diffNum+1) + ( o.pos[i] ? o.pos[i].left : 0 ) + "px";
                o.list[i].style.top = ( o.pos[i] ? o.pos[i].top : 0 ) + "px";
                break;
            case "right" :
                o.list[i].style.left = o.con.offsetWidth / o.viewNum * (diffNum-1) + ( o.pos[i] ? o.pos[i].left : 0 ) + "px";
                o.list[i].style.top = ( o.pos[i] ? o.pos[i].top : 0 ) + "px";
                break;
            case "top" :
                o.list[i].style.left = ( o.pos[i] ? o.pos[i].left : 0 ) + "px";
                o.list[i].style.top = o.con.offsetHeight / o.viewNum * (diffNum+1) + ( o.pos[i] ? o.pos[i].top : 0 ) + "px";
                break;
            case "bottom" :
                o.list[i].style.left = ( o.pos[i] ? o.pos[i].left : 0 ) + "px";
                o.list[i].style.top = o.con.offsetHeight / o.viewNum * (diffNum-1) + ( o.pos[i] ? o.pos[i].top : 0 ) + "px";
                break;
        }

        targetLeft = ( ( o.direction == "left" || o.direction == "right" ) ? o.con.offsetWidth / o.viewNum * diffNum : 0 ) + ( o.pos[i] ? o.pos[i].left : 0 );
        targetTop = ( ( o.direction == "top" || o.direction == "bottom" ) ? o.con.offsetHeight / o.viewNum * diffNum  : 0 ) + ( o.pos[i] ? o.pos[i].top : 0 );
    }

    o.targetPos[i] = {left:targetLeft, top:targetTop };
    TweenMax.to(o.list[i], o.duration, {left:o.targetPos[i].left, top:o.targetPos[i].top, ease: o.ease } );
}
